//           PdbToCitoscape.cc
//  Thu Jun 2008
//  Copyright  2008  michele
//  <vid1998@email.it>>

#include "StructureNetwork.h"
#include <string>

using namespace Biopool;
using namespace std;

string input_file, file_list;
double set_max_distance;

void sShowHelp();
int  ChooseNetwork(string, bool, bool, bool, bool, double&);

int main(int nArgs, char* argv[])
{	
	
	bool alpha = getArg( "-alpha", nArgs, argv);
	bool closatom = getArg( "-closatom", nArgs, argv);
	bool print_all_HB = getArg("-printallhbs", nArgs, argv);
	bool set_distance = getArg("d", set_max_distance, nArgs, argv, 0.0);

if (nArgs == 1)
{
    sShowHelp();
    return 1;
}

if (getArg( "h", nArgs, argv)) //Chiama la funzione sShowHelp () se viene l'argomento e -h
{
    sShowHelp();
    return 1;
}
 
// Argomenti passati alla funzione getArg in tools. Carica il file PDB
getArg( "i", input_file, nArgs, argv, "!"); 
getArg( "I", file_list, nArgs, argv, "!");
		
if ((input_file == "!")&&(file_list == "!"))
{
	cerr << "Missing input file. Use -h to get help.\n";
	return 1;
}

if(input_file != "!")
{
	ChooseNetwork(input_file, alpha, closatom, print_all_HB, set_distance, set_max_distance);
}
	
else

	if (file_list != "!")
	{		
		ifstream input(file_list.c_str());
		
		if(!input)
    	{
			cerr << "ERROR: " << file_list << " not Found!\n\n";
			return 1;
		}
		
		string file;
		int error = 0;

		while (input.peek() != '0' && !input.eof() && error != 1)
		{
			input >> file; //assegno il flusso dell'oggeto input alla stringa file

			error=ChooseNetwork(file, alpha, closatom, print_all_HB, set_distance, set_max_distance);
		
			skipToNewLine(input);
		} 
  
		input.close();
	}
	return 0;
}

//Help del programma
void sShowHelp()
{	
	cout << "\nCalculate distances between aminoacids\n"
	<< "\n"
	<< "Options: \n\n"
	<< "\t -i           \t\t Upload a pdb file from a pre-established path\n\n"
	<< "\t -I           \t\t Upload a series of pdb files from a file list\n\n"	
	<< "\t --alpha      \t\t Calculate distance between alfa carbons\n\n"
	<< "\t --closatom   \t\t Calculate distance considering the closest atom\n\n"
	<< "\t --printallhbs\t\t If it's present print Cytoscape files\n"
	<< "\t              \t\t containing information of all hydrogen bonds formed\n"
	<< "\t              \t\t between two residues defined in contact\n\n"
	<< "\t -d           \t\t If it's present set the distance of contact to the define value\n\n" 
	<< "\t example: ./Pdb_to_Cytoscape [-UPLOAD OPTION] upload path [--CALCULATION OPTION] [--PRINT OPTION] [-DISTANCE LIMIT OPTION] define distance\n\n"
	<< "\t 		Directories with results are created in the same path of the input file\n\n"
	<< "\t      The default limit of contact's distance is set to 5 A° for closatom and 8.5 A° for alpha\n"
	<< endl;
}

/* 
	Sceglie il tipo di file di rete da generare a seconda dei parametri di input
	dati al programma
*/
int ChooseNetwork(string input_file, bool alpha, bool closatom, bool print_all_HB, bool set_distance, double& set_max_distance)
{
	
		if ((alpha == true)&&(closatom == false))		  
		{		
			
			StructureNetwork sn(input_file);
			
			//cout << "set_max_distance =" << set_distance << " max distance" << set_max_distance << endl;
			
			if (set_max_distance != 0.0)
			{
				sn.SetMaxDistanceOfAlpha(set_max_distance);
			}
			
			//cout << "max Distance of alpha" << sn.GetMaxDistanceOfAlpha() << endl;
			
			sn.CalculateCAlphaDistance();
			
			sn.ImportHydrogenBond(input_file);
			
			sn.CalculateSaltBridge();
			
			sn.CalculateDisulfideBond();
			
			sn.PrintCytoscapeFiles(print_all_HB);
			
			return 0;
		}			
			
		if ((closatom == true)&&(alpha == false))
		{
			
			StructureNetwork sn(input_file);
			
			//cout << "set_max_distance =" << set_distance << " max distance" << set_max_distance << endl;
			
			if (set_max_distance != 0.0)
			{
				sn.SetMaxDistanceOfClosest(set_max_distance);
			}
			
			//cout << "max Distance of closest" << sn.GetMaxDistanceOfClosest() << endl;

			sn.CalculateClosestAtomDistance();
			
			sn.ImportHydrogenBond(input_file);
			
			sn.CalculateSaltBridge();
			
			sn.CalculateDisulfideBond();
			
			sn.PrintCytoscapeFiles(print_all_HB);	
			
			return 0;
		}
			
		if ((alpha == false)&&(closatom == false))
		{
			cerr << "Missing parameter for the type of distance to be calculated. Use -h to get help.\n";
			return 1;
		}
	
		if ((alpha == true)&&(closatom == true))
		{
			cerr << "Too many parameters simultaneously. Use -h to get help.\n";
			return 1;
		}

}
